home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
et
/
et3_0-a1.lha
/
et3
/
src
/
Text.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-26
|
11KB
|
599 lines
#ifdef __GNUG__
#pragma implementation
#endif
#include "Text.h"
#include "Class.h"
#include "Error.h"
#include "RegularExp.h"
#include "Mark.h"
#include "Port.h"
#include "OrdColl.h"
#include "Math.h"
//---- formating properties ----------------------------------------------------
byte TextCharMap[] = {
cTextBreak|cTextPara, /* 0x00 */
0, /* 0x01 */
0, /* 0x02 */
0, /* 0x03 */
0, /* 0x04 */
0, /* 0x05 */
0, /* 0x06 */
0, /* 0x07 */
0, /* 0x08 */
0, /* 0x09 */
cTextBreak|cTextPara, /* 0x0a */
0, /* 0x0b */
cTextBreak, /* 0x0c */
cTextBreak, /* 0x0d */
0, /* 0x0e */
0, /* 0x0f */
0, /* 0x10 */
0, /* 0x11 */
0, /* 0x12 */
0, /* 0x13 */
0, /* 0x14 */
0, /* 0x15 */
0, /* 0x16 */
0, /* 0x17 */
0, /* 0x18 */
0, /* 0x19 */
0, /* 0x1a */
0, /* 0x1b */
0, /* 0x1c */
0, /* 0x1d */
0, /* 0x1e */
0, /* 0x1f */
};
static TextChanges changeRec;
//---- VisualMark -----------------------------------------------------
NewMetaImpl0(VisualMark,Mark);
VisualMark::VisualMark() : Mark(0, 0, eStateNone, eMarkFixedSize)
{
}
void VisualMark::CalcExtent()
{
}
int VisualMark::Base()
{
return GetExtent().y;
}
Point VisualMark::GetExtent()
{
return gPoint0;
}
void VisualMark::Draw(Point, Rectangle, Rectangle, bool)
{
}
void VisualMark::SendDown(int, int, void *)
{
}
void VisualMark::SetContainer(class VObject *)
{
}
bool VisualMark::WantsInput(Point)
{
return FALSE;
}
class Command *VisualMark::Input(Point, Token&, class Clipper *)
{
return 0;
}
class VObject *VisualMark::GetVObject()
{
return 0;
}
//---- Text ------------------------------------------------------------
NewAbstractMetaImpl(Text,Object, (TP(marks), TP(observers), T(tabWidth)));
Text::Text()
{
Init();
}
Text::~Text()
{
if (marks) {
marks->FreeAll();
SafeDelete(marks);
}
if (observers)
CleanupObservers(observers);
}
void Text::Init()
{
marks= 0;
tabWidth= cTabw;
observers= 0;
paraStyle= new_ParaStyle();
charStyle= gCharStyles->Default();
}
void Text::InitNew()
{
Init();
}
int Text::GrowSize(int minSize)
{
if (cMaxInt - minSize > minSize)
return minSize+minSize;
int d= minSize-Size();
int m= Math::Min(2000, d);
if (cMaxInt - Size() > m)
return Size()+m;
Error("GrowSize", "Cannot grow text");
return 0;
}
void Text::ReplaceRange(int, int, Text *, int, int)
{
AbstractMethod("ReplaceRange");
}
void Text::Cut(int from,int to)
{
if (marks)
marks->Replace(from, to, 0);
Text *nullText= MakeScratchText(0, 0);
ReplaceRange(from, to, nullText, 0, 0);
SafeDelete(nullText);
Send(cIdNone, eTextDeleted, changeRec(from, to));
}
void Text::Paste(Text *src, int from, int to)
{
if (marks)
marks->Replace(from, to, src->End());
ReplaceRange(from, to, src, 0, src->End());
Send(cIdNone, eTextReplaced, changeRec(from, to, src->End()));
}
void Text::Copy(Text *dst, int from, int to)
{
dst->ReplaceRange(0, dst->End(), this, from, to);
}
void Text::CopyInStr(byte*, int, int, int)
{
AbstractMethod("CopyInStr");
}
void Text::Insert(byte c, int from, int to)
{
Text *t= MakeScratchText(&c, 1);
Paste(t, from, to);
SafeDelete(t);
}
void Text::InsertStr(int from, int to, byte *str, int len)
{
if (len == -1 && str)
len= strlen((char*)str);
Text *t= MakeScratchText(str, len);
Paste(t, from, to);
SafeDelete(t);
}
void Text::ReplaceWithStr(byte *buf, int len)
{
InsertStr(0, End(), buf, len);
}
void Text::SetFStringVL(char *fmt, va_list va)
{
byte *buf= (byte*)strvprintf(fmt, va);
ReplaceWithStr(buf, -1);
SafeDelete(buf);
}
void Text::SetFString(char *va_(fmt), ...)
{
va_list ap;
va_start(ap,va_(fmt));
SetFStringVL(va_(fmt), ap);
va_end(ap);
}
int Text::Search(
RegularExp *rex, int *nMatched, int start, int range, bool dir
)
{
int pos;
char *s= AsString();
if (dir == cSearchForward)
pos= rex->SearchForward (s, nMatched, start, Size(), range, 0);
else
pos= rex->SearchBackward (s, nMatched, start, Size(), range, 0);
delete s;
return pos;
}
bool Text::IsParaStart(int at)
{
return (at <= 0) || IsPara((*this)[at-1]);
}
bool Text::IsParaEnd(int at)
{
return (at >= Size()) || IsPara((*this)[at]);
}
Text *Text::MakeScratchText(byte *, int)
{
AbstractMethod("MakeScratchText");
return 0;
}
Text* Text::Save(int from, int to)
{
if (!CheckRange(Size(), from, to))
Error("Save", "Out of range from= %d to=%d size= %d", from, to, Size());
Text *t= (Text*)this->New();
Copy(t, from, to);
return t;
}
void Text::Append(byte c)
{
int at= Math::Max(0, End());
Insert(c, at, at);
}
byte& Text::operator[](int )
{
static byte dummyc= '\0';
AbstractMethod("operator[]");
return dummyc;
}
void Text::Empty()
{
Cut(0, End());
}
int Text::Size()
{
AbstractMethod("Size");
return 0;
}
void Text::GetWordRange(int at, int *start, int *end)
{
register int i;
if (!CheckRange(Size(), at, at))
return;
for (i= at-1; i >= 0 && Isinword((*this)[i]); i--)
;
*start= i+1;
for (i= at; i < Size() && Isinword((*this)[i]); i++)
;
*end= i;
}
void Text::GetParaRange(int at, int *start, int *end)
{
register int i, ch;
if (!CheckRange(Size(), at, at))
return;
for (i= at-1; i >= 0; i--) {
ch= (*this)[i];
if (IsPara(ch))
break;
}
*start= i+1;
for (i= at; i < Size(); i++) {
ch= (*this)[i];
if (IsPara(ch))
break;
}
*end= Math::Min(Size(), i+1);
}
int Text::FindLastBreak(int from)
{
for (int i= from-1; i >= 0; i--)
if (IsBreak((*this)[i]))
break;
return i;
}
int Text::FindNextBreak(int from)
{
for (int i= from; i < Size(); i++)
if (IsBreak((*this)[i]))
break;
return i;
}
void Text::SetDefTab(int t)
{
tabWidth= t;
}
int Text::GetDefTab()
{
return tabWidth;
}
TextIter *Text::MakeIterator(int,int)
{
AbstractMethod("MakeIterator ");
return 0;
}
//---- style access
void Text::SetCharStyle(TxtCharProp what, int, int, const CharStyleSpec &st)
{
charStyle= gCharStyles->ChangeProperty(charStyle, what, st);
Send(cIdNone, eTextChangedRange, changeRec(0, Size()));
}
void Text::SetParaStyle(TxtParaProp what, int, int, const ParaDesc &pd)
{
paraStyle= gParaStyles->ChangeProperty(paraStyle, what, pd);
Send(cIdNone, eTextChangedRange, changeRec(0, Size()));
}
CharStyle *Text::GetCharStyle(int)
{
return charStyle;
}
CharStyle *Text::GetCurrentCharStyle()
{
return 0;
}
ParaStyle *Text::GetParaStyle(int)
{
return paraStyle;
}
void Text::SetFont(Font *fd, int from, int to)
{
SetCharStyle(eTxtCPFontAll, from, to, CharStyleSpec(fd));
}
Font *Text::GetFont(int)
{
return charStyle->GetFont();
}
void Text::ResetCurrentCharStyle()
{
}
//---- TextPainter contract
int Text::GetNextFontChange(int, CharStyle *&sp)
{
sp= charStyle;
return cMaxInt;
}
byte Text::GetMarkChar()
{
return 0;
}
VisualMark *Text::GetVisualMarkAt(int)
{
return 0;
}
bool Text::IsVisualMark(int)
{
return FALSE;
}
byte *Text::GetLineAccess(byte**, int, int)
{
AbstractMethod("GetLine");
return 0;
}
//---- conversion
char *Text::AsString()
{
int s= Size();
char *buf= new char[s];
CopyInStr((byte*)buf, s, 0, s);
return buf;
}
OStream& Text::PrintOn(OStream &s)
{
Object::PrintOn(s);
return s << charStyle SP << paraStyle SP;
}
IStream& Text::ReadFrom(IStream &s)
{
Object::ReadFrom(s);
return s >> charStyle >> paraStyle;
}
OStream& Text::PrintOnAsPureText(OStream &s)
{
AbstractMethod("PrintOnAsPureText");
return s;
}
IStream& Text::ReadFromAsPureText(IStream &s, long)
{
AbstractMethod("ReadFromAsPureText");
return s;
}
bool Text::IsEmpty()
{
return End() == 0;
}
void Text::AddMark(Mark *m)
{
if (marks == 0)
marks= new MarkList;
marks->Add(m);
}
Mark *Text::RemoveMark(Mark *m)
{
if (marks == 0)
marks= new MarkList;
return marks->Remove(m);
}
Iterator *Text::GetMarkIter()
{
if (marks == 0)
marks= new MarkList;
return marks->MakeIterator();
}
MarkList *Text::GetMarkList()
{
if (marks == 0)
marks= new MarkList;
return marks;
}
void Text::InspectorId(char *b, int s)
{
for (int i= 0; i < Math::Min(s-1, Size()-1); i++)
b[i]= (*this)[i];
b[i]= '\0';
}
bool Text::IsEqual(Object *text)
{
if (text == 0 || ! text->IsKindOf(Text))
return FALSE;
byte *p1= (byte*)AsString();
byte *p2= (byte*)text->AsString();
int equal= StrCmp(p1, p2, -1, sortmap) == 0;
SafeDelete(p1);
SafeDelete(p2);
return equal;
}
u_long Text::Hash()
{
u_long hash;
byte *p= (byte*)AsString();
hash= strhash(p);
return hash;
}
//---- observing ----------------------------------------------------------
Collection *Text::MakeObserverColl()
{
return observers= new OrdCollection(4);
}
Collection *Text::GetObservers()
{
return observers;
}
void Text::DestroyObserverColl()
{
SafeDelete(observers);
}
void Text::SetObserverColl(Collection *cp)
{
SafeDelete(observers);
observers= cp;
}
//----- class TextIter ----------------------------------------------------
TextIter::TextIter(Text *s,int from,int to)
{
ct= s;
ce= Math::Max(from,0);
upto= Math::Min(to,s->Size());
}
TextIter::~TextIter()
{
}
void TextIter::Reset(Text *s,int from,int to)
{
ct= s;
ce= Math::Max(from,0);
upto= Math::Min(to,s->Size());
}
int TextIter::operator()(int *, LineDesc*)
{
return cEOT;
}
int TextIter::GetPos()
{
return ce;
}
Font *TextIter::FontAt(int)
{
return ct->GetFont();
}
int TextIter::Unget()
{
return ce= unget;
}
int TextIter::Token(int*, LineDesc*)
{
return cEOT;
}
int TextIter::GetLastPos() // get last position
{
return unget;
}
void TextIter::SetPos(int newPos)
{
ce= newPos;
}
AutoTextIter::AutoTextIter(Text *t, int from, int to)
{
ti= t->MakeIterator(from, to);
}